package org.shijiagen.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.shijiagen.clients.*;
import org.shijiagen.param.ProductHotParam;
import org.shijiagen.param.ProductIdsParam;
import org.shijiagen.param.ProductSaveParam;
import org.shijiagen.param.ProductSearchParam;
import org.shijiagen.pojo.Picture;
import org.shijiagen.pojo.Product;
import org.shijiagen.product.mapper.PictureMapper;
import org.shijiagen.product.mapper.ProductMapper;
import org.shijiagen.product.service.ProductService;
import org.shijiagen.to.OrderToProduct;
import org.shijiagen.utils.R;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper,Product> implements ProductService {

    private final CategoryClient categoryClient;

    private final ProductMapper productMapper;

    private final PictureMapper pictureMapper;

    private final SearchClient searchClient;

    private final CartClient cartClient;

    private final OrderClient orderClient;

    private final CollectClient collectClient;

    @Override
    public R search(ProductSearchParam productSearchParam) {
        return searchClient.searchProduct(productSearchParam);
    }

    @Override
    @Cacheable(value = "list.product", key = "#ids")
    public List<Product> productListByIds(List<Integer> ids) {
        return productMapper.selectBatchIds(ids);
    }

    @Override
    @Cacheable(value = "list.product", key = "#categoryName", cacheManager = "cacheManagerHour")
    public Page<Product> promo(String categoryName) {
        R cateResult = categoryClient.byName(categoryName);
        if(cateResult.getCode().equals(R.FAIL_CODE)){
            return null;
        }
        LinkedHashMap<String, Object> category = (LinkedHashMap<String,Object>) cateResult.getData();
        return productMapper.selectPage(new Page<>(1, 7),new QueryWrapper<Product>().eq("category_id",category.get("category_id"))
                .orderByDesc("product_sales"));
    }

    @Override
    @Cacheable(value = "list.product", key = "#productHotParam.categoryName")
    public Page<Product> hots(ProductHotParam productHotParam) {
        R categoryResult = categoryClient.hotsCategory(productHotParam);
        if(categoryResult.getCode().equals(R.FAIL_CODE)){
            return null;
        }
        return productMapper.selectPage(new Page<>(1,7),new QueryWrapper<Product>().in("category_id",(List<Integer>)categoryResult.getData())
                .orderByDesc("product_sales"));
    }

    @Override
    @Cacheable(value = "list.category", key = "#root.methodName", cacheManager = "cacheManagerDay")
    public R categoryList() {
        return categoryClient.list();
    }

    /**
     * 根据类别id查询对应类别商品，如果传入集合为空则查询全部商品
     *
     * @param productIdsParam
     * @return
     */
    @Override
    @Cacheable(value = "list.product", key = "#productIdsParam.categoryID+'-'+#productIdsParam.currentPage+'-'+#productIdsParam.pageSize")
    public Page<Product> byCategory(ProductIdsParam productIdsParam) {
        List<Integer> categoryID = productIdsParam.getCategoryID();
        if (categoryID.isEmpty()) {
            return productMapper.selectPage(new Page<Product>(productIdsParam.getCurrentPage(),productIdsParam.getPageSize()),new QueryWrapper<>());
        }
        return productMapper.selectPage(new Page<Product>(productIdsParam.getCurrentPage(),productIdsParam.getPageSize()),
                new QueryWrapper<Product>().in("category_id",categoryID));
    }

    @Override
    @Cacheable(value = "product", key = "#productID")
    public Product detail(Integer productID) {
        return productMapper.selectById(productID);
    }

    @Override
    @Cacheable(value = "picture", key = "#productID")
    public List<Picture> pictures(Integer productID) {
        return pictureMapper.selectList(new QueryWrapper<Picture>().eq("product_id",productID));
    }

    @Override
    public List<Product> allList() {
        return productMapper.selectList(null);
    }

    @Override
    public void subNumber(List<OrderToProduct> orderToProduct) {
        Map<Integer, Integer> productSales = orderToProduct.stream().collect(Collectors.toMap(OrderToProduct::getProductId, OrderToProduct::getNum));
        List<Product> products = productMapper.selectBatchIds(productSales.keySet());
        products.forEach(product -> {
            // 减去库存
            product.setProductNum(product.getProductNum() - productSales.get(product.getProductId()));
            // 增加销售量
            product.setProductSales(product.getProductSales() + productSales.get(product.getProductId()));
        });
        // 修改完毕的商品进行保存
        this.updateBatchById(products);
    }

    @Override
    public Long adminCount(Integer categoryId) {
        return baseMapper.selectCount(new QueryWrapper<Product>().eq("category_id",categoryId));
    }

    @Override
    @CacheEvict(value = "list.product",allEntries = true)
    public R adminSave(ProductSaveParam productSaveParam) {
        Product product = new Product();
        BeanUtils.copyProperties(productSaveParam,product,"pictures");
        // 插入商品数据
        baseMapper.insert(product);
        String pictures = productSaveParam.getPictures();
        if (StringUtils.hasText(pictures)) {
            String[] p = pictures.split("\\+");
            // 插入商品图片地址
            Arrays.stream(p).forEach(url->{
                Picture picture = new Picture();
                picture.setProductId(product.getProductId());
                picture.setProductPicture(url);
                pictureMapper.insert(picture);
            });
        }
        searchClient.saveProduct(product);
        return R.ok("商品添加成功！");
    }

    @Override
    @Caching(
            evict = {
                    @CacheEvict(value = "list.product",allEntries = true),
                    @CacheEvict(value = "product",key = "#product.productId")
            }
    )
    public R adminUpdate(Product product) {
        productMapper.updateById(product);
        searchClient.saveProduct(product);
        return R.ok("商品数据更新成功");
    }

    @Override
    @Caching(
            evict = {
                    @CacheEvict(value = "list.product",allEntries = true),
                    @CacheEvict(value = "product",key = "#productId")
            }
    )
    public R adminRemove(Integer productId) {
        if(cartClient.removeCheck(productId).getCode().equals("004") || orderClient.removeCheck(productId).getCode().equals("004")){
            return R.fail("购物车或订单中有商品引用无法删除");
        }
        Product removeProduct = productMapper.selectById(productId);
        // 删除商品
        productMapper.deleteById(productId);
        // 删除商品图片
        pictureMapper.delete(new QueryWrapper<Picture>().eq("product_id",productId));
        // 删除收藏中的商品
        collectClient.removeByPid(productId);
        // 更新es索引
        searchClient.removeProduct(removeProduct);
        return R.ok("删除成功");
    }
}
